/*
 * Copyright (c) 2013, SRI International
 * All rights reserved.
 * Licensed under the The BSD 3-Clause License;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 * 
 * http://opensource.org/licenses/BSD-3-Clause
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 
 * Neither the name of the aic-web-praise nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.sri.ai.lpitools.gwtgui.client.components.querypanel;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.LayoutPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
import com.google.gwt.user.client.ui.SuggestBox;
import com.sri.ai.lpitools.cobra.gwtutil.dataobjects.shared.EvidenceInfo;
import com.sri.ai.lpitools.cobra.gwtutil.dataobjects.shared.UserInfo;
import com.sri.ai.lpitools.gwtgui.client.RPCService;
import com.sri.ai.lpitools.gwtgui.client.Toolkit;
import com.sri.ai.lpitools.gwtgui.client.components.dialogs.MessageDialog;
import com.sri.ai.lpitools.gwtgui.client.components.manager.UserListener;
import com.sri.ai.lpitools.gwtgui.client.util.JSONUtil;

public class EvidencePanel extends LayoutPanel implements UserListener{

	private static final String AD_HOC_QUERY_STRING = "Ad Hoc";
	private ListBox evidenceSelectionBox;
	private SuggestBox evidenceText;	
	private MultiWordSuggestOracle suggestBoxOracle = new MultiWordSuggestOracle();
	private List<String> evidence;		
	private final Toolkit toolkit;
	
	public EvidencePanel(Toolkit tk) {
		this.toolkit = tk;
	
		this.evidenceSelectionBox = new ListBox();
		this.evidenceSelectionBox.addStyleName("aic-SelectionBox");
		

		this.evidenceText = new SuggestBox(suggestBoxOracle);
		this.evidenceText.setStyleName("aic-TextBox");
		evidence = new ArrayList<String>();
		


		//add a change listener to the text box to update the evidenceSelectionManager
		this.evidenceText.getValueBox().addChangeHandler(new ChangeHandler() {
			@Override
			public void onChange(ChangeEvent event) {
				toolkit.getEvidenceDataManager().setEvidenceText(evidenceText.getText());
			}
		});

		//add a selection listener to populate the evidenceSelectionBox
		this.evidenceSelectionBox.addChangeHandler(new ChangeHandler() {
			@Override
			public void onChange(ChangeEvent event) {
				int selectedIndex = evidenceSelectionBox.getSelectedIndex();
				if (selectedIndex > 0) {
					String selectedName = evidenceSelectionBox.getItemText(selectedIndex);

					toolkit.getEvidenceDataManager().setSelectedEvidenceName(selectedName);
					getEvidenceText(selectedName, toolkit.getUserManager().getCurrentUser().getUser());

				} else {
					//for the unselected (or Ad Hoc) case, set the selected evidence name to NULL
					
					toolkit.getEvidenceDataManager().setSelectedEvidenceName(null);
					setEvidenceText("");
				}
				
			}
		});
		
		//add a user changed listener

		toolkit.getUserManager().addUserListener(this);
		//if a user is logged in, then update the queries list
		loggedInUserChanged(toolkit.getUserManager().getCurrentUser());
		//layout the components
		this.add(evidenceSelectionBox);
		this.add(evidenceText);

		
		this.setWidgetTopHeight(evidenceSelectionBox, 0, Unit.PCT, 2, Unit.EM);
		this.setWidgetBottomHeight(evidenceText, 0, Unit.PCT, 2, Unit.EM);
	}
	


	protected void getEvidenceText(String selectedName, String user) {
		RPCService.Util.getInstance().getEvidence(user, selectedName, new AsyncCallback<EvidenceInfo>() {
		
		@Override
		public void onSuccess(EvidenceInfo result) {
			
			if (result != null) {
				setEvidenceText(result.getEvidence());
			} else {
				MessageDialog.showMessageDialog("Got a null string evidence string back");
			}
		}

		@Override
		public void onFailure(Throwable caught) {
			MessageDialog.showMessageDialog(caught.getMessage());
		}
	});
	
}

	/**
	 * will query the aicManager for the list of queries for the given user
	 */
	protected void updateEvidenceList() {
		evidenceSelectionBox.clear();
		//add a special Ad Hock selection item
		evidenceSelectionBox.addItem(AD_HOC_QUERY_STRING);
		
		//get the queries for this user
		for (String info : evidence) {
			evidenceSelectionBox.addItem(info);
		}
		
		evidenceSelectionBox.setSelectedIndex(0);
	}

	public void addToSuggestions(String suggestion) {
		suggestBoxOracle.add(suggestion);
	}

	
	protected void setEvidenceText(String text) {
		evidenceText.setText(text);
		toolkit.getEvidenceDataManager().setEvidenceText(text);
	}
	
	private void getEvidenceList(String user) {

		evidence.clear();
		RPCService.Util.getInstance().getEvidenceList(user, new AsyncCallback<String>() {
			
			@Override
			public void onSuccess(String result) {
				
				if (result == null) {
					MessageDialog.showMessageDialog("Null response for getEvidenceList query");
					return;
				}
				if(result.startsWith("ERROR.")){
				} else {
					List<EvidenceInfo> list = JSONUtil.getEvidenceInfoList(result);
					for(EvidenceInfo current: list){
						evidence.add(current.getEvidenceTitle());
					}
					
				}
				updateEvidenceList();
			}

			@Override
			public void onFailure(Throwable caught) {
				MessageDialog.showMessageDialog(caught.getMessage());
			}
		});
	}



	@Override
	public void loggedInUserChanged(UserInfo newUser) {
		evidenceSelectionBox.clear();
		setEvidenceText("");
		if (newUser != null) {
			getEvidenceList(newUser.getUser());
		} else {
			evidence = new ArrayList<String>();
		}
	}

}

